﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Data;
using Utils;

namespace StockModel
{
    [DebuggerDisplay("Connection = {_dbClient.ConnectionString}")]
    public class ExchangeMarketDataSource : DataSourceBase
    {
        #region Constants

        private const string ExchangeMarketQuery = "SELECT * FROM [ExchangeMarkets]";
        private const string ExchangeMarketByNameQuery = "SELECT * FROM [ExchangeMarkets] WHERE Name = '{0}'";
        private const string ExchangeMarketHolidaysQuery = "SELECT * FROM [ExchangeMarketHolidays] WHERE MarketId IN (SELECT Id FROM ExchangeMarkets WHERE Name = '{0}')";

        #endregion

		#region Public Methods

		public ExchangeMarketDataSource(IDataBaseClient dbClient) : base(dbClient)
        {
        }

        public ExchangeMarket Load(ExchangeMarketName name)
        {
            DataTable dataRead = base.DataBaseClient.ExecuteQuery(string.Format(ExchangeMarketByNameQuery,name.ToString()));

            if (dataRead.Rows.Count != 1)
            {
                throw new DataException(string.Format("The number of rows at the database containing the market {0} is different from 1",name.ToString()));
            }

            TimeSpan preOpen = (TimeSpan)dataRead.Rows[0]["PreOpen"];
            TimeSpan open = (TimeSpan)dataRead.Rows[0]["Open"];
            TimeSpan closed = (TimeSpan)dataRead.Rows[0]["Closed"];

            object closingTemp = dataRead.Rows[0]["Closing"];
            TimeSpan? closing = closingTemp is DBNull ? null : (TimeSpan?)closingTemp;

            ExchangeMarket result = new ExchangeMarket(name, preOpen, open, closing, closed);
            result.Holidays.AddRange(this.LoadHolidays(result.Name, DateTime.Now.Year));

            return result;
        }

        public IEnumerable<ExchangeMarket> Load()
        {
            List<ExchangeMarket> result = new List<ExchangeMarket>();

			DataTable dataRead = base.DataBaseClient.ExecuteQuery(ExchangeMarketQuery);

            foreach (DataRow row in dataRead.Rows)
            {
                TimeSpan preOpen = (TimeSpan)row["PreOpen"];
                TimeSpan open = (TimeSpan)row["Open"];
                TimeSpan closed = (TimeSpan)row["Closed"];

                object closingTemp = row["Closing"];
                TimeSpan? closing = closingTemp is DBNull ? null : (TimeSpan?)closingTemp;
                
                ExchangeMarketName name = (ExchangeMarketName)Enum.Parse(typeof(ExchangeMarketName), row["Name"].ToString());
                ExchangeMarket market = new ExchangeMarket(name, preOpen, open, closing, closed);
                market.Holidays.AddRange(this.LoadHolidays(market.Name,DateTime.Now.Year));
                result.Add(market);
            }

            return result;
        }

        #endregion

        #region Private Methods

        private IEnumerable<DateTime> LoadHolidays(ExchangeMarketName name, int year)
        {
            List<DateTime> result = new List<DateTime>();

			DataTable dataRead = base.DataBaseClient.ExecuteQuery(string.Format(ExchangeMarketHolidaysQuery, name));

            foreach (DataRow row in dataRead.Rows)
            {
                DateTime day = (DateTime)row["Day"];
                if (day.Year == year)
                {
                    result.Add(day);
                }
            }

            return result;
        }

        #endregion

    }
}
